<!DOCTYPE html>
<html lang="en">

<head>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Dexcalibur - Welcome</title>

    <!-- styles -->
    <!--## pages/inc/tpl_css.html ##-->

    <!--## pages/inc/tpl_js_d3.html ##-->

    <style>
    

    html,
    body {
    height: 100%;
    }

    body {
        display: -ms-flexbox;
        display: -webkit-box;
        display: flex;
        -ms-flex-align: center;
        -ms-flex-pack: center;
        -webkit-box-align: center;
        align-items: center;
        -webkit-box-pack: center;
        justify-content: center;
        padding-top: 40px;
        padding-bottom: 40px;
        background: linear-gradient(120deg, #4B0000 0%, #000000 100%), linear-gradient(300deg, #1E0000 0%, #0038FF 100%, #0038FF 100%), linear-gradient(65deg, #00FFFF 0%, #FF00A8 100%), linear-gradient(185deg, #FF0000 10%, #1400FF 95%), radial-gradient(100% 140% at 100% 0%, #00A3FF 0%, #C10097 100%);
        background-blend-mode: color-dodge, overlay, difference, color-dodge, normal;  
    }

    .form-splash {
        width: 100%;
        max-width: 330px;
        padding: 15px;
        margin: 0 auto;
    }
    .form-splash .checkbox {
        font-weight: 400;
    }
    .form-splash .form-control {
        position: relative;
        box-sizing: border-box;
        height: auto;
        padding: 10px;
        font-size: 16px;
    }
    .form-splash .form-control:focus {
        z-index: 2;
    }
    .form-splash input[type="email"] {
        margin-bottom: -1px;
        border-bottom-right-radius: 0;
        border-bottom-left-radius: 0;
    }
    .form-splash input[type="password"] {
        margin-bottom: 10px;
        border-top-left-radius: 0;
        border-top-right-radius: 0;
    }

    .splash-ctn {
        width: 40em;
    }

    .splash-ctn div.card-header {
        text-align:center;
    }

    .splash {
        background-color: #262722;
        color: #FFF;
    }

    .splash-menu {
        margin-left:0px;
        padding-left: 0px;
    }

    .splash-menu div.card {
        border-radius:0px;
    }

    .dxc-dark li.list-group-item,
    .splash-home li.list-group-item,
    .splash-menu li.list-group-item {
        /*background-color: #262722;*/
        background-color: #3d3f38;
        
        color: #FFF;
        font-size: 0.8em;
        cursor:pointer;
    }

    .dxc-dark li.list-group-item:hover,
    .splash-home li.list-group-item:hover,
    .splash-menu li.list-group-item:hover {
        background-color: #43463e;
        color: rgb(190, 190, 190);
        font-size: 0.8em;
        cursor:pointer;
    }

    .splash-detail {
        /*background-image: url("/dist/img/dexcalibur_logo_black2.png");
        background-position: 40px  10px;*/
        color:#fff;
    }

    table.dxc-compact-table {
        background-color: #262722;
        margin-top: 1em;
    }
    table.dxc-compact-table > tr{
        border: 1px solid gray;
    }

    .dxc-panel-message {
        text-align: center;
        background-color: #43463e;
        color: rgb(190, 190, 190);
        padding: 0.5rem;
        margin-top:0.5rem;
    }
    
    .splash-panel > h4 {
        color:yellow;
    }

    .splash-open-apk .multi-collapse{
        margin-top:1em;
    }

    #projectTypeOpt {
        padding-top:1em;
    }

    </style>
</head>

<body class="dxc-dark">

    
        <!-- Navigation -->
        <!-- pages/inc/menu.html -->
        

            <div class="row">
                <div class="col-md-8 col-md-offset-2">

                    <div class='row splash' style="width: 60rem;">
                    <div class="col-md-4 splash-menu">

                        <div class="card bg-secondary text-white" style="width:100%">
                            <div class="card-header">
                                Action
                            </div>
                            <ul class="list-group list-group-flush">
                                <li class="list-group-item dxc-open-project">
                                    <span class='fa fa-folder-open'>&nbsp;</span>&nbsp;Open an existing project ...
                                </li>
                                <li class="list-group-item dxc-open-apk">
                                    <span class='fa fa-upload'>&nbsp;</span>&nbsp;New project
                                </li>
                                <li class="list-group-item dxc-select-app">
                                    <span class='fa fa-mobile'>&nbsp;</span>&nbsp;Select an application
                                </li>
                            </ul>
                            <div class="card-header">
                                Settings
                            </div>
                            <ul class="list-group list-group-flush">
                                <li class="list-group-item dxc-api-manager" >
                                    <span class='fa fa-android'>&nbsp;</span>&nbsp;Android APIs manager
                                </li>
                                <li class="list-group-item dxc-device-manager">
                                    <span class='fa fa-mobile'>&nbsp;</span>&nbsp;Device manager
                                </li>
                                <!--<li class="list-group-item dxc-plugins">
                                    <span class='fa fa-archive'>&nbsp;</span>&nbsp;Plugins
                                </li>-->
                            </ul>
                    </div> 
                    </div>
                    <div class="col-md-8 splash-panel splash-home" style="text-align: center"> 
                        <img class="logo" src="/dist/img/dexcalibur_logo_black2.png"  style="margin-top:-10em">
                        <small>Recents :</small> 
                        <ul class="list-group list-group-flush dxc-project-list" style="text-align:left;overflow:auto;height:10em;" id="dxcProjectList"></ul>
                    </div>
                    <div class="col-md-8 splash-panel splash-open-project" style="display:none"> 
                        <h4>Workspace</h4>
                        <small>
                            Click to open an existing project ...
                        </small>
                        <ul class="list-group list-group-flush dxc-project-list" id="dxcProjectList2"></ul>
                    </div>
                    <div class="col-md-8 splash-panel splash-open-apk" style="display:none;font-size:0.8em;"> 
                        <h4>New project</h4>

                        <div class="form-row">
                            <div class="col-md-10 mb-3">
                                <label for="dxcSelectApk_projectUID">Project UID</label><br>
                                <i>For each project a folder is created into Dexcalibur workspace. The project UID is the folder name.</i>
                                <input type="text" class="form-control form-control-sm" id="dxcSelectApk_projectUID" placeholder="Project name" value="" required>
                                <div class="valid-feedback">
                                    Looks good!
                                </div>
                                <div class="invalid-feedback">
                                    This project UID is invalid. Project name must be unique and must contain only: A-Z a-z 0-9 - _
                                </div>
                            </div>
                        </div>

                        <b>What do you want ?</b>
                        <p id="dxcSelectApk_typeMsg" class="invalid-feedback" style="display: none">Please select file/app to analyze</p>
                        <div class="form-check">
                            <input class="form-check-input" type="radio" name="projectType" id="projectTypeDownload" value="download" required>
                            <label class="form-check-label" for="projectTypeDownload">
                                Download a remote file
                            </label>
                        </div>

                        <div class="form-check">
                            <input class="form-check-input" type="radio" name="projectType" id="projectTypeUpload" value="upload" required>
                            <label class="form-check-label" for="projectTypeUpload">
                                Upload an APK
                            </label>
                        </div>

                        <div class="form-check">
                            <input class="form-check-input" type="radio" name="projectType" id="projectTypeFs" value="fromfs" required>
                            <label class="form-check-label" for="projectTypeFs">
                                Enter absolute path of the APK
                            </label>
                        </div>


                        <div id="projectTypeOpt"></div>

                        <b class="mt-lg-2">Database: </b>
                        <div class="form-row">
                            <div class="col-md-10 mb-3" id="projectConnectors"></div>
                        </div>

                        <br>
                        <div class="form-row">
                            <div class="col-md-10 mb-3">
                                <label for="dxcApkAPI"><b>Choose the Plaform/API for the analysis:</b> </label>
                                <select class="form-control form-control-sm" id="dxcApkAPI">
                                    <option disabled>Select a platform/API version</option>
                                    <optgroup label="------------------------------">
                                        <option value="dev">Android version of target device</option>
                                        <option value="min" selected>Min Android version supported by App</option>
                                        <option value="max">Max Android version supported by App</option>
                                    </optgroup>
                                    <optgroup label="------------------------------" id="dxc-select-platform"></optgroup>
                                </select>
                            </div>
                        </div>

                        <div class="form-row">
                            <div class="col-md-10 mb-3">
                                <label for="dxcSelectDev2"><b>Select the default device:</b> </label>
                                <select class="form-control form-control-sm dxc-select-dev" id="dxcSelectDev2" >
                                    <option>Select a device</option>
                                    <optgroup label="Enrolled device" id="dxc-optDevices2"></optgroup>
                                </select>
                                <div class="valid-feedback">
                                    Looks good!
                                </div>
                                <div class="invalid-feedback">
                                    Device unknown or not enrolled.
                                </div>
                            </div>
                        </div>

                        <div class="form-row">
                            <div class="col-md-8">&nbsp;</div>
                            <div class="col-md-4">
                                <button class='btn btn-success createProject'><span class="fa fa-bolt"></span>&nbsp;Continue</button>
                            </div>
                        </div>
                    </div>

                    <div class="col-md-8 splash-panel splash-select-app" style="display:none"> 
                        <h4>Select an application to analyze</h4>
                        <small>
                            Select a device and an application to analyze ... 
                        </small>
                        <select class="form-control form-control-sm dxc-select-dev" id="dxcSelectDev" >
                            <option>Select a device</option>
                            <optgroup id="dxc-optDevices"></optgroup>
                        </select>
                        <div class="dxc-panel-message" id="dxcSelectAppProgress" style="display: none;">
                            <div class="progress">
                                <div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%"></div>
                            </div>
                            <small id="dxcSeclectAppProgMsg">Loading application ...</small>
                        </div>
                        <table class="table table-sm ttable-hover dxc-compact-table" id="dxcAppList" style="display: none; overflow:auto; height:200px">
                            <thead>
                                <th>App name</th>
                                <th>Action</th>
                            </thead>
                            <tbody id="dxcAppListBody" style=""></tbody>
                        </table>
                    </div>


                    <div class="col-md-8 splash-panel splash-api-manager" style="display:none"> 
                        <h4>Platform Manager</h4>
                        <small>
                            Additionnal platform can be install from here (require internet). It extends Dexcalibur by providing
                            a more accurate analysis. If you think an application use a function introduced recently, then ensure 
                            to have the right Android version installed.
                        </small>
                        <!--<p>
                                Let's imagine your application use function introduced into Android 10. If 
                                Dexcalibur is not properly configured, then the analysis can be performed by using Android 7.0.0 and 
                                the functions could be not detected.    
                        </p>-->
                        <table class="table table-sm table-hover dxc-compact-table">
                            <thead>
                                <th>Name</th>
                                <th>Version</th>
                                <th>Source</th>
                                <th>Action</th>
                            </thead>
                            <tbody id="dxcApiList"></tbody>
                        </table>
                    </div>

                    <div class="col-md-8 splash-panel splash-device-manager" style="display:none"> 
                            <h4>Device Manager</h4>
                            <small>
                                Here, you can "enroll" a new device. In fact, Dexcalibur will: 
                                <ul>
                                    <li>push Frida server into the device</li>
                                    <li>gather metadata about context to improve hook interpretation</li>
                                    <li>identify device configuration : TEE, GMS version, ...</li>
                                    <li>identify constructor specific assets</li>
                                </ul>
                            </small>
                            <div class="text-right text-sm">
                                <a class="btn btn-secondary btn-sm dxc-dev-connect"><span class="fa fa-wifi"></span>&nbsp;Connect over TCP...</a>&nbsp;
                                <a class="btn btn-primary btn-sm dxc-dev-refresh"><span class="fa fa-refresh"></span>&nbsp;Refresh</a>
                            </div>
                            <table class="table table-sm table-hover dxc-compact-table">
                                <thead>
                                    <th>Device ID</th>
                                    <th>Model</th>
                                    <th>Online</th>
                                    <th>Enrolled</th>
                                    <th>Action</th>
                                </thead>
                                <tbody id="dxcDeviceList"></tbody>
                            </table>

                            <div class="text-right text-sm mb-5">
                                <a class="btn btn-sm dxc-dev-killsrv text-warning"><span class="fa fa-bolt"></span>&nbsp;Restart ADB server</a>&nbsp;
                                <a class="btn btn-danger btn-sm dxc-dev-clear"><span class="fa fa-trash"></span>&nbsp;Remove all</a>&nbsp;
                            </div>
                        </div>
                </div>
                 
                 
                </div>
            </div>

            <div class="modal fade" id="confirmModal" tabindex="-1" role="dialog" aria-labelledby="confirmModalLabel" aria-hidden="true">
                <div class="modal-dialog modal-lg" role="document">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h3 class="modal-title" id="confirmModalLabel">Confirmation</h3>
                        </div>
                        <div class="modal-body" id="confirmModalMessage">-</div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-secondary" data-dismiss="modal" id="confirmModalCancel">Cancel</button>
                            <button type="button" class="btn btn-danger" id="confirmModalConfirm">Confirm</button>
                        </div>
                    </div>
                </div>
            </div>


            <div class="modal fade" id="dxcLoadingModal" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
                <div class="modal-dialog">
                  <div class="modal-content">                   
                    <div class="modal-body">
                        <div class="progress">
                            <div class="progress-bar progress-bar-striped progress-bar-animated" id="dxcLoadingModalProgress" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100" style="width: 100%"></div>
                        </div>
                        <div style="width:100%;background-color:#eee;margin-top:1em;font-size:0.8em" id="dxcLoadingModalMessage"></div>
                        <pre style="width:100%;background-color:#eee;margin-top:1em;font-size:0.8em" id="dxcLoadingModalConsole"></pre>
                    </div>
                  </div>
                </div>
              </div>

              <div class="modal fade" id="dxcDevConnectModal" tabindex="-1" role="dialog" aria-labelledby="devConnectModalLabel" aria-hidden="true">
                <div class="modal-dialog">
                  <div class="modal-content">                   
                    <div class="modal-body">
                 
                        
                        <label for="devip">Device IP address</label>
                        <input type="text" id="devip" name="devip" class="form-control form-control-sm" />
                        <label for="devport">Device Port</label>
                        <input type="number" id="devport" name="devport" class="form-control form-control-sm" />
                
                        <label for="dxc-selConnDev">If the device is already enrolled, select it. Else lets empty or select 'None'</label>
                        <select class="form-control form-control-sm dxc-select-dev" id="dxc-selConnDev">
                            <option value="none" disabled selected>Select a device</option>
                            <optgroup id="dxc-connDevices"></optgroup>
                        </select>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
                        <button type="button" class="btn btn-primary" id="addDevConnect">Add</button>
                    </div>
                  </div>
                </div>
              </div>

            <div class="modal fade" id="dxcEnrollModal" tabindex="-1" role="dialog" aria-labelledby="enrollOptModalLabel" aria-hidden="true">
                <div class="modal-dialog">
                  <div class="modal-content">                 
                    <div class="modal-body" >
                        <div class="progress">
                            <div class="progress-bar progress-bar-striped progress-bar-animated" id="dxcEnrollModalProgress" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100" style="width: 100%"></div>
                        </div>
                        <pre style="width:100%;background-color:#eee;margin-top:1em;" id="dxcEnrollConsole"></pre>
                    </div>
                    <div class="modal-body" style="display:none">
                        <input type="radio" name="dxcEnrollType" id="dxcEnrollType" class="form-control form-control-sm" placeholder="lets empty if remote install" />
                        <input type="radio" name="dxcEnrollType" id="dxcEnrollTypeOpt" class="form-control form-control-sm" placeholder="lets empty if remote install" />

                        <b>Frida (optionnal)</b>
                        <label for="dxcEnrollFridapath">Client path</label>
                        <input type="text" name="dxcEnrollFridapath" id="dxcEnrollFridapath" class="form-control form-control-sm" />

                        <label for="dxcEnrollFridaLoc">Location of server binary into the device</label>
                        <input type="text" name="dxcEnrollFridaLoc" id="dxcEnrollFridaLoc" class="form-control form-control-sm" placeholder="Default is /data/local/tmp" />

                        <label for="dxcEnrollFridaRemote">Server binary remote URL</label>
                        <input type="type" id="dxcEnrollFridaRemote" class="form-control form-control-sm" placeholder="lets empty if remote install" />

                        <b>Profiling</b>
                        <label for="dxcEnrollProfileAPI">Analyze Android framework</label>
                        <input type="checkbox" name="dxcEnrollProfileAPI" id="dxcEnrollProfileAPI" class="form-control form-control-sm" value="1" />
                    </div>
                  </div>
                </div>
              </div>
           <!--
              <div class="card splash-ctn bg-secondary text-white">
                <div class="row">
                    <div class="col-md-6">

                        <div class="card-header">
                            New project
                        </div>
                        Select the action :
                        <div class="card-body">
                            <input type="radio" id="splash-new-upl">
                            <label for="splash-new-upl">Upload an APK</label><br>
                            <input type="radio" id="splash-new-upl">
                            <label for="splash-new-upl">Select an application into a coneected device</label>
                        </div>

                    </div>
                    <div class="col-md-6">
                        <div class="card-header">
                            Open an existing project
                        </div>
                    </div>
                </div>
              </div>-->

        <!-- /#page-wrapper -->


    <!-- /#wrapper -->

    <!--## pages/inc/tpl_js_splash.html ##-->
    <!--## pages/inc/tpl_ace_js.html ##-->

    <script>

    function setupAceEditor(id){
        var editor = ace.edit(id);
        editor.setTheme("ace/theme/monokai"); //
    
        editor.setOptions({
            maxLines: 50, 
            fontSize: "12pt"
        });
        //editor.setUseWorker(false);
        editor.session.setMode("ace/mode/javascript");
    }
   
    function updateDeviceList( pElement){
        $(pElement).empty();
        
        //$(pElement).append('<tr><td colspan=6 class="text-center">If your device is connected but nothing appears, check device screen.</td></tr>');

        DexcaliburAPI.device.list((vData)=>{
                    
                    let data = JSON.parse(vData), d=null, ip=null, b=null;
                    let act = '', bridges='';

                    $(pElement).empty();

                    for(let i=0; i<data.devices.length; i++){
                        d = data.devices[i];
                        bridges = '';

                        for(let shortname in d.bridges){
                            b = d.bridges[shortname];

                            bridges += `
                                <br><span class="fa fa-${b.transport=='U'?'usb':'wifi'} ml-2"></span>&nbsp;${shortname}&nbsp;<span style="font-size:0.9em;color:yellow">(${b.transport=='U'? b.usbQualifier : b.ip+':'+b.port})</span>
                            `;
                        }

                        if(d.authorized==false){
                            act = '-';
                        }else{
                            act = (d.connected==true)?(d.enrolled==false? '<span class="badge badge-pill bg-primary enroll" data-target="#dxcEnrollModal" data-dxc-uid="'+d.uid+'">enroll</span>' : '<span class="badge badge-pill bg-primary enroll" data-target="#dxcEnrollModal" data-dxc-uid="'+d.uid+'">re-enroll</span>'):'';
                        }

                        if(Object.keys(d.bridges).indexOf('adb+tcp')>-1){
                            act += '&nbsp;<span class="badge badge-pill badge-warning connectbridge" data-dxc-uid="'+d.uid+'">TCP connect</span>' 
                        }

                        $(pElement).append(`
                        <tr>
                            <td>
                                ${DexcaliburAPI.anonymize(DexcaliburAPI.ui.htmlEncode(d.id))}${bridges}
                            </td>
                            <td>
                                ${ d.model}
                            </td>
                            <td style="text-align:center">
                                ${ d.connected==true? (d.authorized==true? '<span class="fa fa-check text-success"></span>' : '<span class="fa fa-exclamation-triangle text-danger" data-toggle="tooltip" data-placement="bottom" title="Device : Computer unauthorized. You should allow USB debugging first"></span>') : '' }
                            </td>
                            <td>
                                ${d.enrolled==true? '<span class="fa fa-check text-success"></span>' : '<i class="text-warning">Enrollment required</i>'}
                            </td>
                            <td>
                                ${act} 
                            </td>
                        </tr>
                        `);
                    }
                });
    }

    function updateProjectList( pElement){
        DexcaliburAPI.workspace.list((vData)=>{
                let el = $(pElement);
                let data = JSON.parse(vData);

                el.empty();

                if(data.projects.length > 0){
                    data.projects.map( (vName)=>{
                        el.append(`
                            <li class="list-group-item">
                                <div class="row">
                                    <!--<div class="col-md-4">Missing image</div>-->
                                    <div class="col-md-7">
                                        <!-- <div class="proj-desc"><i>No description set</i></div> -->
                                        <span class="proj-pkg">${DexcaliburAPI.anonymize(vName)}</span>
                                    </div>
                                    <div class="col-md-5">
                                        <div class="badge badge-pill badge-warning open-project" dxc-id="${vName}">
                                            <span class="fa fa-link proj-pkg"></span>&nbsp;Open
                                        </div>
                                        <div class="badge badge-pill badge-danger del-project" dxc-id="${vName}">
                                            <span class="fa fa-trash proj-pkg" dxc-id="${vName}"></span>&nbsp;Delete
                                        </div>
                                    </div>
                                </div>
                            </li>
                        `)
                    });
                }else{
                    el.append(`
                                <li class="list-group-item">
                                    <div class="row">
                                        <div class="col-md-12">Workspace is empty</div>
                                    </div>
                                </li>
                            `);
                }
            });
    }

    function openProject( pUID){


        $('#dxcLoadingModalProgress').removeClass('bg-danger');
        $('#dxcLoadingModalConsole').html("Performing analysis ... (it can take 30s to 5min depending of application size)<br>If Dexcalibur crashes, increase heap size with '--max-heap 8192' options.");
        $("#dxcLoadingModal").modal();
        
        DexcaliburAPI.workspace.open( pUID, (vData)=>{
            let data = JSON.parse(vData)
            
            if(data.success == true){
                location.href = "/pages/index_v2.html"; 
            }else{
                alert("error");
                $('#dxcLoadingModalProgress').addClass('bg-danger');
            }
        });
    }


    function flagInputAsInvalid( pEl) {
        pEl.removeClass("is-valid");
        pEl.addClass("is-invalid");
    }


    function requestConfirm( pMessage, pCallbacks){

        $("#confirmModalMessage").html(pMessage);
        $("#confirmModalConfirm").off('click');
        $("#confirmModalCancel").off('click');
        $("#confirmModal").modal();

        $("#confirmModalConfirm").click( function(){
            $("#confirmModal").modal('toggle');
            pCallbacks.onConfirm();
        });
        $("#confirmModalCancel").click( function(){
            $("#confirmModal").modal('toggle');
            pCallbacks.onCancel();
        });
    }

    function removeAllDevice( pViewID){
        requestConfirm(
            "Are you sure to remove all devices ? This action cannot be undone. All devices should be enrolled again.",
            {
                onConfirm: function(){
                    DexcaliburAPI.device.clear(null,{
                        onSuccess: function(){
                            updateDeviceList(pViewID);
                        },
                    onError: (pData)=>{
                        pData = JSON.parse(pData.responseText);

                        alert(pData.msg);
                        /*
                        $(pElementID+' div.modal-body').prepend(`
                            <div class="alert alert-danger alert-dismissible fade show" role="alert">
                                ${pData.msg}
                                <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                                    <span aria-hidden="true">&times;</span>
                                </button>
                            </div>
                        `);*/
                    }
                    })
                }
            }
        );
    }

    function deleteProject( pProjectUID){
        requestConfirm(
            "Are you sure to delete project '"+DexcaliburAPI.ui.htmlEncode(pProjectUID)+"' ? Files will be removed from disk.",
            {
                onConfirm: function(){
                    DexcaliburAPI.workspace.delete( pProjectUID, (vData)=>{
                        let data = JSON.parse(vData)
                        
                        if(data.success == true){
                            location.href = "/pages/splash.html"; 
                        }else{
                            alert('An error occured. Operation failed.')
                        }
                    })
                }
            }
        );
    }

    function deviceConnectModal( pCallback){
        $('#addDevConnect').off('click');
        $('#addDevConnect').click((pEl)=>{
            pCallback( $('#devip').val(), $('#devport').val(), $('#dxc-selConnDev').val(), '#dxcDevConnectModal');
            
        });

        DexcaliburAPI.device.list((vData)=>{
                        
            let data = JSON.parse(vData), dev=null, did=null;
            
            $('#dxc-connDevices').empty();

            for(let i in data.devices){
                dev = data.devices[i];
                if(dev.enrolled == true){

                    $('#dxc-connDevices').append(`
                        <option value="${dev.uid}">[${dev.model}] ${DexcaliburAPI.anonymize(dev.id)}</options>
                    `);
                }
            }

            $('#dxcDevConnectModal').modal();
        });
    }

    $(document).ready(function() {

        updateProjectList("#dxcProjectList");

        $(document).on('click','span.connectbridge',pEl => {
            let devid = pEl.currentTarget.getAttribute("data-dxc-uid");
            DexcaliburAPI.device.connect(null, null, devid, {
                onSuccess: function(){
                    alert('success');
                },
                onError: function(){
                    alert('error');
                }
            })
        });

        const SCOPES = {
            "home": {
                el:  null,
                view: "splash-home"
            },
            "open-project": {
                el:  null,
                view: "splash-open-project",
                action: function(vEl){
                    updateProjectList("#dxcProjectList2");
                }
            },
            "open-apk": {
                el:  null,
                view: "splash-open-apk",
                action: (vEl)=>{
                    
                    DexcaliburAPI.platform.list((vData)=>{
                        
                        let data = JSON.parse(vData), platf=null;
                        
                        $('#dxc-select-platform').empty();

                        for(let i in data.platforms){
                            platf = data.platforms[i];
                            $('#dxc-select-platform').append(`
                                <option value="${platf.uid}">[${platf.source}] ${platf.name} ${platf.version} (${platf.vendor})${platf.installed==true?"   -   INSTALLED":""}</options>
                            `);
                        }

                        updateDeviceList('#dxcDeviceList2');
                    });

                    DexcaliburAPI.device.list((vData)=>{
                        
                        let data = JSON.parse(vData), dev=null;
                        
                        $('#dxc-optDevices2').empty();

                        for(let i in data.devices){
                            dev = data.devices[i];
                            //if(dev.connected == true){
                                $('#dxc-optDevices2').append(`
                                    <option value="${dev.uid}">[${dev.model}] (${DexcaliburAPI.anonymize(dev.id)}) ${dev.enrolled==true?"   -   ENROLLED":""}</options>
                                `);
                           // }
                        }
                    });

                    DexcaliburAPI.connector.list({ onSuccess: (vData)=>{
                        let data = JSON.parse(vData);
                        let ele =  $('#projectConnectors');
                        let k=0;

                        ele.empty();

                        for(let i in data){
                            ele.append(`
                                <div  class="custom-control custom-radio rounded ${k==0?'bg-secondary':'border border-secondary'}">
                                    <input type="radio" id="${data[i].type}" ${k==0?'checked':''} name="dxcConnector" value="${data[i].type}"  class="custom-control-input ml-lg-5">
                                    <label for="${data[i].type}"  class="custom-control-label"><i>${data[i].name}</i><br>${data[i].description}</label>
                                </div>
                            `);
                            k++;
                        }
                    }});
                }
            },
            "select-app": {
                el:  null,
                view: "splash-select-app",
                action: (vEl)=>{
                    
                    DexcaliburAPI.device.list((vData)=>{
                        
                        let data = JSON.parse(vData), dev=null;
                        
                        $('#dxc-optDevices').empty();

                        for(let i in data.devices){
                            dev = data.devices[i];
                            if(dev.connected == true){
                                $('#dxc-optDevices').append(`
                                    <option value="${dev.uid}">[${dev.model}] (${DexcaliburAPI.anonymize(dev.id)}) ${dev.enrolled==true?"   -   ENROLLED":""}</options>
                                `);
                            }else{
                                $('#dxc-optDevices').append(`
                                    <option disabled value="${dev.uid}">[${dev.model}] (${DexcaliburAPI.anonymize(dev.id)}) ${dev.enrolled==true?"   -   ENROLLED":""} (disconnected)</options>
                                `);
                            }
                        }
                    });
                }
            },
            "import": {
                el:  null,
                view: "splash-import"
            },
            "api-manager": {
                el:  null,
                view: "splash-api-manager",
                action: function(vEl){
                    DexcaliburAPI.platform.list((vData)=>{
                    
                        let data = JSON.parse(vData), installMsg;

                        $('#dxcApiList').empty();

                        for(let i in data.platforms){

                            if(data.platforms[i].installed === true){
                                installMsg = "<span class='fa fa-check text-success'></span>&nbsp;Installed";
                            }else{
                                installMsg = "<i class='text-primary dxc-install-plt' dxc-id='"+data.platforms[i].uid+"'><span class='fa fa-download'></span>&nbsp;Click to install<i>";
                            }

                            $('#dxcApiList').append(`
                            <tr>
                                <td>${data.platforms[i].name}</td>
                                <td>${data.platforms[i].version}</td>
                                <td>${data.platforms[i].source}</td>
                                <td>
                                    <i>${installMsg}</i>   
                                </td>
                            </tr>
                            `);
                        }
                    });
                }
            },
            "device-manager": {
                el:  null,
                view: "splash-device-manager",
                action: function(vEl){
                    updateDeviceList('#dxcDeviceList');
                }
            },
            "plugin-manager": {
                el:  null,
                view: "splash-home"
            },

        }

        let context = "home";

        for(let i in SCOPES){
            $(`.dxc-${i}`).click(function(vData){
                //alert(i,context);
                $(`.splash-${context}`).css("display","none");
                $(`.splash-${i}`).css("display","block");
                context = i;
                if(SCOPES[i].action !== null) SCOPES[i].action(vData);
            })
        }

         // Add the following code if you want the name of the file appear on select
        $(".custom-file-input").on("change", function() {
            var fileName = $(this).val().split("\\").pop();
            $(this).siblings(".custom-file-label").addClass("selected").html(fileName);
        });

        $('#dxcSelectApk_projectUID').on("change", (vEl)=>{
            let e = $('#dxcSelectApk_projectUID');


            DexcaliburAPI.workspace.checkAvailabilityProjectUID(
                e.val(),
                function( vData){
                    let rep = JSON.parse(vData);

                    e.removeClass("is-valid");
                    e.removeClass("is-invalid");

                    if(rep.availability){
                        e.addClass("is-valid");
                    }else{
                        e.addClass("is-invalid");
                    }
                });
        });

        $('#dxcSelectDev2').on('change', (vEl)=> {
            let e = $('#dxcSelectDev2');

            DexcaliburAPI.workspace.checkDevice(
                e.val(),
                function( vData){
                    let rep = JSON.parse(vData);

                    e.removeClass("is-valid");
                    e.removeClass("is-invalid");

                    if(rep.availability){
                        e.addClass("is-valid");
                    }else{
                        e.addClass("is-invalid");
                    }
                });
        });

        $(document).on("click",'i.dxc-install-plt',(pEl)=>{
            let uid = pEl.currentTarget.getAttribute('dxc-id');
            
            pEl.currentTarget.innerHTML = `
                <div class="progress">
                <div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100" style="width: 100%"></div>
                </div>
            `;            

            DexcaliburAPI.platform.install(uid, {
                onSuccess: (vData)=>{
                    let data = JSON.parse(vData), installMsg="";

                    if(data.status === true){
                        pEl.target.parentNode.innerHTML = "<span class='fa fa-check text-success'></span>&nbsp;Installed";
                    }else{
                        pEl.target.innerHTML = "<i class='text-primary dxc-install-plt' dxc-id='"+uid+"'><span class='fa fa-refresh'></span>&nbsp;Retryl<i>";
                    }
                }
            })
        })

        $(document).on("click",'div.open-project',(pEl)=>{

            let uid = pEl.currentTarget.getAttribute('dxc-id');

            openProject(uid);
        });
        $(document).on("click",'div.del-project',(pEl)=>{

            let uid = pEl.currentTarget.getAttribute('dxc-id');

            deleteProject(uid);
        });
        $(document).on("click",'a.dxc-dev-clear', (pEl)=>{
            removeAllDevice('#dxcDeviceList');
        });
        $(document).on("click",'a.dxc-dev-refresh',(pEl)=>{
            updateDeviceList('#dxcDeviceList');
        });
        $(document).on("click",'a.dxc-dev-connect',(pEl)=>{
            $('.alert').alert('close');

            deviceConnectModal(function(pIP, pPort, pDevID, pElementID){
                DexcaliburAPI.device.connect(pIP, pPort, pDevID, {
                    onSuccess: (pData)=>{
                        $(pElementID).modal('toggle');
                        updateDeviceList('#dxcDeviceList');
                    },
                    onError: (pData)=>{
                        pData = JSON.parse(pData.responseText);
                        let err = 'Unknow error';
                        
                        if(typeof pData.msg === 'string')
                            err = pData.msg;
                        else if(pData.msg.stderr !== null)
                            err = pData.msg.stderr;
                        else if(pData.msg.stdout !== null)
                            err = pData.msg.stdout;


                        $(pElementID+' div.modal-body').prepend(`
                            <div class="alert alert-danger alert-dismissible fade show" role="alert">
                                ${err}
                                <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                                    <span aria-hidden="true">&times;</span>
                                </button>
                            </div>
                        `);
                    }
                });
            });
        });
        $(document).on('change', '#dxcSelectDev', function(pEvent){
                console.log(pEvent.currentTarget.value);
                $("#dxcSelectAppProgress").css("display","block");
                DexcaliburAPI.device.listApplications( pEvent.currentTarget.value, false, {
                    onSuccess: (vData)=>{
                        $("#dxcSelectAppProgress").css("display","none");
                        $("#dxcAppList").css("display","block");

                        let data = JSON.parse(vData);

                        $("#dxcAppListBody").empty();
                        for(let i in data.apps){
                            $("#dxcAppListBody").append(`
                                <tr>
                                    <td>${DexcaliburAPI.ui.htmlEncode(DexcaliburAPI.anonymize(data.apps[i].packageIdentifier))}</td>
                                    <td>
                                        <span class="badge badge-pill badge-warning scan-app" dxc-device="${data.device}" dxc-app-file="${data.apps[i].packagePath}" dxc-uid="${data.apps[i].packageIdentifier}">Scan</span>&nbsp;
                                    </td>
                                </tr>
                            `);
                        }
                }
            });
        })
        $(document).on('click', 'span.enroll', (pEv)=>{

            let uid = pEv.currentTarget.getAttribute('data-dxc-uid');


            $('#dxcEnrollModal').modal();


            task = DexcaliburAPI.device.getEnrollStatus( 1000,
                function(x){
                        let data = JSON.parse(x);

                        if(data.msg == null) return;
                        
                        if(data.percent === 100){
                            task.stop();
                        }

                        if(data.extra !== null){
                            switch(data.extra){
                                case "success":
                                    $("#dxcEnrollModalProgress").addClass('bg-success');
                                    task.stop();
                                    $('#dxcEnrollModal').modal('toggle');
                                    updateDeviceList('#dxcDeviceList');
                                    break;
                                case "error":
                                    $("#dxcEnrollModalProgress").addClass('bg-danger');
                                    task.stop();
                                    //$("#install_auto_progress").removeClass();
                                    break;
                            }
                        }
                        $("#dxcEnrollModalProgress").css("width",data.progress+"%");
                        $("#dxcEnrollConsole").html(data.msg); 
                    }
                );

            task.start();
            
            DexcaliburAPI.device.enroll( uid, {}, {}, {
                onSuccess: function(vData){
                    $("#dxcEnrollModalProgress").css("width","10%");
                    $("#dxcEnrollConsole").html("starting ..."); 
                    task.stop();
                }
            });
        });
        $(document).on('change', 'input[name=projectType]', (pEvent)=>{
            let id = pEvent.currentTarget.id;
            let ctn = '';

            switch(id){
                case 'projectTypeDownload':
                    ctn = `
                        <div class="input-group input-group-sm" id="projectDownloadCollapse">
                            <div class="input-group-prepend">
                                <div class="input-group-text">URL</div>
                            </div>
                            <input type="text" class="form-control form-control-sm" id="projectDownloadURL" placeholder="http://..." value="">
                        </div>`;
                    break;
                case 'projectTypeUpload':
                    ctn = `
                            <div class="custom-file" id="projectUploadCollapse">
                                <form method="post" id="projectUploadForm" enctype='multipart/form-data'>
                                    <input type="file" class="custom-file-input" name="projectUploadedFile" id="projectUploadedFile">
                                    <label class="custom-file-label" for="projectUploadedFile">Choose file</label>
                                </form>
                            </div>`;
                    break;
                case 'projectTypeFs':
                    ctn = `
                        <div class="input-group input-group-sm" id="projectFromfsCollapse">
                            <div class="input-group-prepend">
                                <div class="input-group-text">Path</div>
                            </div>
                            <input type="text" class="form-control form-control-sm" id="projectLocalPath" placeholder="/home/..." value="">
                        </div>`;
                    break;
            }

            $('#projectTypeOpt').empty();
            $('#projectTypeOpt').html(ctn);
        });

        $(document).on('click','a.dxc-dev-killsrv',(pEl)=>{
            DexcaliburAPI.device.bridge.kill('ADB',{
                onSuccess: function(pData){
                    let data = JSON.parse(pData);
                    console.log(pData);
                    alert( data.success? 'Success' : 'An error occured (see logs)')
                },
                onError: function(pData){
                    let data = JSON.parse(pData.responseText);

                    alert('Error : '+data.msg);
                }
            })
        });

        $(document).on('change', 'input.custom-file-input', function(pEvent){
            if(pEvent.currentTarget.files.length > 0){
                pEvent.currentTarget.labels[0].innerHTML = DexcaliburAPI.ui.htmlEncode(pEvent.currentTarget.files[0].name); 
            }
        });

        var newProjectCallback = function( vData){
            let data = JSON.parse(vData);
            
            if(data.success == true){
                location.href = "/pages/index_v2.html";
            }else{

                console.log($('#dxcLoadingModal'));
                $('#dxcLoadingModal').modal('toggle');

                if(data.hasOwnProperty('code')){
                    if(data.code==1){
                        flagInputAsInvalid($('#dxcSelectApk_projectUID'));
                    }else if (data.code==2){
                        flagInputAsInvalid($('#dxcSelectDev2'));
                    }
                }


            }
        };

        $(document).on('click','.scan-app',(pEvent)=>{

            // normalize project uid
            let projectUID = "", c;
            let id = pEvent.currentTarget.getAttribute('dxc-uid');
            for(let i=0; i<id.length ; i++){
                c = id[i];
                if((c>='a' && c<='z')||(c>='A' && c<='Z')||(c>='0' && c<='9')||(c=='-')||(c=='_')){
                    projectUID += c;
                }
                else if(c=='.'){
                    projectUID += '_';
                }
            }

            let params = {
                name: projectUID,
                dev: pEvent.currentTarget.getAttribute('dxc-device'),
                path: pEvent.currentTarget.getAttribute('dxc-app-file'),
                type: 'select'
            };

            $('#dxcLoadingModalProgress').removeClass('bg-danger');
            $('#dxcLoadingModalConsole').html("Performing analysis ... (it can take 30s to 5min depending of application size)<br>If Dexcalibur crashes, increase heap size with '--max-heap 8192' options.");
            $("#dxcLoadingModal").modal();

            DexcaliburAPI.workspace.newProject(params, { onSuccess:newProjectCallback });
        });

        $(document).on('click',".createProject", (pEvent)=>{
            
            // dxcLoadingModal
            let params = {};

            params.name = $('#dxcSelectApk_projectUID').val();

            if(/^[A-Za-z0-9-_]+$/.test(params.name) == false){
                flagInputAsInvalid($('#dxcSelectApk_projectUID'));
                return;
            }

            params.platform = $('#dxcApkAPI').val();
            params.dev = $('#dxcSelectDev2').val();
            params.connector = $('input[name=dxcConnector]:checked').val();

            var source =
                $('#projectTypeUpload').is(':checked')<<2 |
                $('#projectTypeDownload').is(':checked')<<1 |
                $('#projectTypeFs').is(':checked');

            if(source == 0){
                $('#dxcSelectApk_typeMsg').css('display',"block");
                return ;
            }



            $('#dxcLoadingModal').modal();
            $('#dxcLoadingModalProgress').css('width','10%');
            $('#dxcLoadingModalProgress').addClass('bg-primary');

            if( source==4 ){
                params.type = 'upload';


                DexcaliburAPI.workspace.upload(
                    "#projectUploadForm",
                    "#projectUploadedFile",
                    {
                        onSuccess: function(vData){
                            let data = JSON.parse(vData);

                            if(data.success){
                                $('#dxcLoadingModalProgress').css('width','30%');
                                $('#dxcLoadingModalConsole').html("Upload successfull");
                                params.uploadid = data.upload;
                                console.log(params);
                                DexcaliburAPI.workspace.newProject(params, { onSuccess:newProjectCallback });
                            }else{


                                $('#dxcLoadingModal').modal('toggle');

                                if(data.code==1){
                                    flagInputAsInvalid($('#dxcSelectApk_projectUID'));
                                }else if (data.code==2){
                                    flagInputAsInvalid($('#dxcSelectDev2'));
                                }
                            }
                        }
                    }
                );
            }
            else if( source == 2 ){
                params.type = 'download';
                params.url = $('#projectDownloadURL').val();
                DexcaliburAPI.workspace.newProject(params, { onSuccess:newProjectCallback });
            }
            else if( source == 1){
                params.type = 'fromfs';
                params.path = $('#projectLocalPath').val();
                DexcaliburAPI.workspace.newProject(params, { onSuccess:newProjectCallback });
            }else{
                $('#dxcLoadingModal').modal('hide');
            }


        });
    });

   

    </script>
</body>

</html>
